using Domain.Examin;
using Domain.User;
using Infratructure.Interface;
using MediatR;
using MES.Server.API.Application.Command.ApprovalProcess;
using Microsoft.EntityFrameworkCore;
using ReturnValue;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace MES.Server.API.Application.Handler.ApprovalProcess
{
    public class SaveApprovalFlowDesignHandler : IRequestHandler<SaveApprovalFlowDesignCommand, ApiResult<bool>>
    {
        private readonly IRepository<ApprovalNodeModel> nodeRepo;
        private readonly IRepository<approvalProcessInstanceModel> processInstanceRepo;
        private readonly IRepository<ApprovalProcessModel> processModelRepo;
        private readonly IRepository<ApprovalAssigneeModel> assigneeRepo;

        public SaveApprovalFlowDesignHandler(
            IRepository<ApprovalNodeModel> nodeRepo,
            IRepository<approvalProcessInstanceModel> processInstanceRepo,
            IRepository<ApprovalProcessModel> processModelRepo,
            IRepository<ApprovalAssigneeModel> assigneeRepo)
        {
            this.nodeRepo = nodeRepo;
            this.processInstanceRepo = processInstanceRepo;
            this.processModelRepo = processModelRepo;
            this.assigneeRepo = assigneeRepo;
        }

        public async Task<ApiResult<bool>> Handle(SaveApprovalFlowDesignCommand request, CancellationToken cancellationToken)
        {
            var result = new ApiResult<bool>();

            try
            {
                // 1. 检查是否已经存在流程定义，没有则创建
                var processModel = await processModelRepo.GetAll()
                    .Where(p => p.Id == request.ProcessId && !p.IsDel)
                    .FirstOrDefaultAsync();

                if (processModel == null)
                {
                    // 创建新的流程定义
                    processModel = new ApprovalProcessModel
                    {
                        Id = request.ProcessId > 0 ? request.ProcessId : DateTime.Now.Ticks,
                        processName = request.ProcessName ?? "采购审批流程",
                        description = "自定义审批流程",
                        status = 1, // 启用状态
                        CreaterPeople = request.CurrentUserId.ToString(),
                        CreateTime = DateTime.Now
                    };
                    await processModelRepo.AddAsync(processModel);
                }

                // 2. 删除原有的节点定义（如果有）
                var existingNodes = await nodeRepo.GetAll()
                    .Where(n => n.processId == processModel.Id && !n.IsDel)
                    .ToListAsync();
                
                foreach (var node in existingNodes)
                {
                    node.IsDel = true;
                    await nodeRepo.UpdateAsync(node);
                }

                // 3. 创建新的节点和连接关系
                Dictionary<string, long> nodeIdMapping = new Dictionary<string, long>();
                
                // 先创建所有节点
                foreach (var nodeInfo in request.Nodes)
                {
                    var newNode = new ApprovalNodeModel
                    {
                        Id = DateTime.Now.Ticks + nodeInfo.NodeType,
                        processId = processModel.Id,
                        nodeName = nodeInfo.NodeName,
                        nodeType = nodeInfo.NodeType,
                        nodeDescription = nodeInfo.NodeDescription,
                        timeLimit = nodeInfo.TimeLimit > 0 ? nodeInfo.TimeLimit : 24
                    };
                    
                    await nodeRepo.AddAsync(newNode);
                    
                    // 保存前端节点ID与数据库节点ID的映射关系
                    nodeIdMapping[nodeInfo.Id] = newNode.Id;
                    
                    // 如果设置了审批人，创建审批人分配记录
                    if (nodeInfo.ApproverUserId.HasValue || nodeInfo.ApproverRoleId.HasValue || nodeInfo.DepartmentId.HasValue)
                    {
                        var assignee = new ApprovalAssigneeModel
                        {
                            Id = DateTime.Now.Ticks,
                            nodeId = newNode.Id,
                            userId = nodeInfo.ApproverUserId,
                            roleId = nodeInfo.ApproverRoleId,
                            departmentId = nodeInfo.DepartmentId,
                            assignType = DetermineAssignType(nodeInfo)
                        };
                        
                        await assigneeRepo.AddAsync(assignee);
                    }
                }
                
                // 设置节点间的连接关系
                foreach (var conn in request.Connections)
                {
                    if (nodeIdMapping.ContainsKey(conn.SourceNodeId) && nodeIdMapping.ContainsKey(conn.TargetNodeId))
                    {
                        var sourceNodeId = nodeIdMapping[conn.SourceNodeId];
                        var targetNodeId = nodeIdMapping[conn.TargetNodeId];
                        
                        // 获取源节点
                        var sourceNode = await nodeRepo.GetValue(sourceNodeId);
                        if (sourceNode != null)
                        {
                            sourceNode.nextnodeId = targetNodeId;
                            await nodeRepo.UpdateAsync(sourceNode);
                        }
                        
                        // 获取目标节点
                        var targetNode = await nodeRepo.GetValue(targetNodeId);
                        if (targetNode != null)
                        {
                            targetNode.prevnodeId = sourceNodeId;
                            await nodeRepo.UpdateAsync(targetNode);
                        }
                    }
                }
                
                // 4. 创建或更新流程实例
                var processInstance = await processInstanceRepo.GetAll()
                    .Where(p => p.productionOrder == request.BusinessId && !p.IsDel)
                    .FirstOrDefaultAsync();
                
                if (processInstance == null)
                {
                    // 创建新的流程实例
                    var startNode = request.Nodes.FirstOrDefault(n => n.NodeType == 1); // 开始节点
                    long startNodeId = startNode != null && nodeIdMapping.ContainsKey(startNode.Id) ? nodeIdMapping[startNode.Id] : 0;
                    
                    processInstance = new approvalProcessInstanceModel
                    {
                        Id = DateTime.Now.Ticks,
                        processId = processModel.Id,
                        productionOrder = request.BusinessId,
                        currentNodeId = startNodeId,
                        initiator = request.CurrentUserId,
                        status = 1, // 进行中
                        starttiome = DateTime.Now
                    };
                    
                    await processInstanceRepo.AddAsync(processInstance);
                }
                else
                {
                    // 更新现有流程实例
                    processInstance.processId = processModel.Id;
                    var startNode = request.Nodes.FirstOrDefault(n => n.NodeType == 1); // 开始节点
                    if (startNode != null && nodeIdMapping.ContainsKey(startNode.Id))
                    {
                        processInstance.currentNodeId = nodeIdMapping[startNode.Id];
                    }
                    
                    await processInstanceRepo.UpdateAsync(processInstance);
                }
                
                result.Code = StatusCode.Success;
                result.Message = "审批流程设计保存成功";
                result.Data = true;
                return result;
            }
            catch (Exception ex)
            {
                result.Code = StatusCode.Fail;
                result.Message = $"保存审批流程设计失败：{ex.Message}";
                result.Data = false;
                return result;
            }
        }
        
        /// <summary>
        /// 确定审批人分配类型
        /// </summary>
        private int DetermineAssignType(ApprovalNodeInfo nodeInfo)
        {
            // 1: 用户, 2: 角色, 3: 部门
            if (nodeInfo.ApproverUserId.HasValue)
                return 1;
            else if (nodeInfo.ApproverRoleId.HasValue)
                return 2;
            else if (nodeInfo.DepartmentId.HasValue)
                return 3;
            else
                return 0;
        }
    }
}
